﻿// ------------------------------------------------------------------------------------
//      Copyright (c) uhavemyword@gmail.com. All rights reserved.
//      Created by Ben at 2/21/2013 10:50:12 AM
// ------------------------------------------------------------------------------------

namespace CP.NLayer.Client.WpfClient.Common
{
    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Windows.Input;
    using CP.NLayer.Resources.UI;
    using CP.NLayer.Service.Contracts;
    using Microsoft.Practices.Prism.Commands;
    using Microsoft.Practices.Unity;

    public class DisplayViewModel<T> : ViewModelBase
    {
        private IInteractionService _interaction;
        private T _selectedItem;
        private ObservableCollection<object> _selectedItems = new ObservableCollection<object>();

        protected IDisplayModelService<T> _service
        {
            get { return DependencyInjection.Container.Resolve<IDisplayModelService<T>>(); }
        }

        public DisplayViewModel(IInteractionService interaction)
        {
            this._interaction = interaction;
            this.AddCommand = new DelegateCommand(ExecuteAddCommand, CanExecuteAddCommand);
            this.EditCommand = new DelegateCommand(ExecuteEditCommand, CanExecuteEditCommand);
            this.DeleteCommand = new DelegateCommand(ExecuteDeleteCommand, CanExecuteDeleteCommand);
            this.RefreshCommand = new DelegateCommand(ExecuteRefreshCommand, CanExecuteRefreshCommand);
            Items = new PagedCollectionView<T>(); 
        }

        public Type EditViewType { get; set; }

        public PagedCollectionView<T> Items { get; set; }

        public T SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                this.RaisePropertyChanged(() => this.SelectedItem);
            }
        }

        public ObservableCollection<object> SelectedItems
        {
            get { return _selectedItems; }
            set
            {
                if (_selectedItems != value)
                {
                    _selectedItems = value;
                    this.RaisePropertyChanged(() => this.SelectedItems);
                }
            }
        }

        public ICommand AddCommand { get; private set; }

        public ICommand EditCommand { get; private set; }

        public ICommand DeleteCommand { get; private set; }

        public ICommand RefreshCommand { get; private set; }

        protected virtual bool CanExecuteAddCommand()
        {
            return true;
        }

        protected virtual void ExecuteAddCommand()
        {
            _interaction.ShowEditView(
                this.EditViewType,
                string.Empty,
                () =>
                {
                    ExecuteRefreshCommand();
                });
        }

        protected virtual bool CanExecuteEditCommand()
        {
            return true;
        }

        protected virtual void ExecuteEditCommand()
        {
            if (this.SelectedItem != null)
            {
                _interaction.ShowEditView(
                this.EditViewType,
                    _service.GetId(this.SelectedItem),
                    () =>
                    {
                        ExecuteRefreshCommand();
                    });
            }
        }

        protected virtual bool CanExecuteDeleteCommand()
        {
            return true;
        }

        protected virtual void ExecuteDeleteCommand()
        {
            if (this.SelectedItems != null && this.SelectedItems.Count > 0)
            {
                _interaction.ShowDeleteConfirmation(
                    string.Format(UiResources.DeleteConfirm, string.Join(", ", this.SelectedItems.Select(x => x.ToString()))),
                    () =>
                    {
                        foreach (T item in SelectedItems)
                        {
                            _service.Delete(item);
                        }
                        ExecuteRefreshCommand();
                    });
            }
        }

        protected virtual bool CanExecuteRefreshCommand()
        {
            return true;
        }

        protected virtual void ExecuteRefreshCommand()
        {
            this.Items.Refresh();
        }
    }
}
